package cn.laixueit.service.impl;

import cn.laixueit.mapper.SkuMapper;
import cn.laixueit.mapper.SpuDetailMapper;
import cn.laixueit.mapper.SpuMapper;
import cn.laixueit.mapper.StockMapper;
import cn.laixueit.pojo.item.Sku;
import cn.laixueit.pojo.item.Spu;
import cn.laixueit.pojo.item.SpuDetail;
import cn.laixueit.pojo.item.Stock;
import cn.laixueit.pojo.result.PageResult;
import cn.laixueit.pojo.vo.SpuVo;
import cn.laixueit.service.BrandService;
import cn.laixueit.service.CategoryService;
import cn.laixueit.service.GoodsService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private BrandService brandService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SpuDetailMapper spuDetailMapper;
    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 分页查询
     * @param key 搜索关键字
     * @param saleable 是否上架
     * @param page 页码
     * @param rows 页码大小
     * @return 分页数据
     */
    public PageResult<SpuVo> page(String key, Boolean saleable, Integer page, Integer rows) {
        PageResult<SpuVo> result = new PageResult<>();

        QueryWrapper<Spu> wrapper = getCondition(key,saleable);

        Page<Spu> p = new Page<>(page, rows);
        // 查询所有spu
        IPage<Spu> spuIPage = spuMapper.selectPage(p, wrapper);

        // 返回的spuvo集合
        ArrayList<SpuVo> spuVos = new ArrayList<>();
        spuIPage.getRecords().forEach(spu -> {
            // 将spu中的属性copy给spuvo中相同的属性
            SpuVo spuVo = new SpuVo();
            BeanUtils.copyProperties(spu,spuVo);

            // 设置spuvo的品牌名
            String brandName = brandService.getById(spu.getBrandId()).getName();
            spuVo.setBname(brandName);

            // 设置spuvo的分类名
            String categoryName = categoryService.getById(spu.getCid3()).getName();
            spuVo.setCname(categoryName);

            spuVos.add(spuVo);
        });

        result.setItems(spuVos);
        result.setTotal(Long.valueOf(spuIPage.getTotal()).intValue());

        return result;
    }

    /**
     * 保存方法
     * @param spuVo
     */
    @Transactional
    public void save(SpuVo spuVo) {
        // 1 保存spu
        spuVo.setSaleable(true);
        spuVo.setValid(true);
        spuVo.setCreateTime(new Date());
        spuVo.setLastUpdateTime(new Date());

        spuMapper.insert(spuVo); // 只会保存对应的属性

        // 2 保存spu detail
        SpuDetail spuDetail = spuVo.getSpuDetail();
        spuDetail.setSpuId(spuVo.getId());
        spuDetailMapper.insert(spuDetail);

        // 3 保存sku
        List<Sku> skuList = spuVo.getSkus();
        skuList.forEach(sku -> {
            sku.setSpuId(spuVo.getId());
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(new Date());
            skuMapper.insert(sku);

            // 保存 stock
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
            stockMapper.insert(stock);
        });

        sendMsg(spuVo.getId(),"insert");

    }

    /**
     * 查询详情
     * @param id
     * @return
     */
    public SpuDetail spuDetail(Long id) {
        SpuDetail spuDetail = spuDetailMapper.selectById(id);
        return spuDetail;
    }

    @Override
    public List<Sku> skuList(Long id) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("spu_id",id);
        List<Sku> skuList = skuMapper.selectByMap(map);
        skuList.forEach(sku -> {
            Stock stock = stockMapper.selectById(sku.getId());
            sku.setStock(stock.getStock());
        });
        return skuList;
    }

    /**
     * 更新spu
     * @param spuVo
     */
    @Transactional
    public void updateGoods(SpuVo spuVo) {
        spuVo.setLastUpdateTime(new Date());
        spuMapper.updateById(spuVo);

        SpuDetail spuDetail = spuVo.getSpuDetail();
        spuDetailMapper.updateById(spuDetail);

        // 先删除原有sku列表
        HashMap<String, Object> map = new HashMap<>();
        map.put("spu_id",spuVo.getId());
        List<Sku> skus = skuMapper.selectByMap(map);
        if(!CollectionUtils.isEmpty(skus)){
            skuMapper.deleteById(map);
            skus.forEach(sku -> {
                stockMapper.deleteById(sku.getId());
            });
        }

        List<Sku> skuList = spuVo.getSkus();
        skuList.forEach(sku -> {
            sku.setSpuId(spuVo.getId());
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(new Date());
            skuMapper.insert(sku);

            // 保存 stock
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
            stockMapper.insert(stock);
        });

        sendMsg(spuVo.getId(),"update");
    }

    @Override
    public Spu findSpuId(Long id) {

        return spuMapper.selectById(id);
    }

    @Override
    public Sku findSkuById(Long skuid) {
        Sku sku = skuMapper.selectById(skuid);
        return sku;
    }

    private QueryWrapper<Spu> getCondition(String key,Boolean saleable){
        QueryWrapper<Spu> wrapper = new QueryWrapper<>();

        if(key!=null){
            wrapper.like("title",key);
        }
        if(null != saleable) {
            wrapper.eq("saleable", saleable);
        }

        return wrapper;
    }

    private void sendMsg(Long id,String type){
        try {
            rabbitTemplate.convertAndSend("item."+type,id);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
